package com.aizuda.boot.modules.business.contract.service.impl;

import com.aizuda.boot.modules.business.contract.dto.SingleResponse;
import com.aizuda.boot.modules.business.contract.dto.UserInfo;
import com.aizuda.boot.modules.business.contract.entity.WorkflowTypeEntity;
import com.aizuda.boot.modules.business.contract.entity.dto.WorkflowTypeAddRequest;
import com.aizuda.boot.modules.business.contract.entity.dto.WorkflowTypeSortRequest;
import com.aizuda.boot.modules.business.contract.entity.dto.WorkflowTypeUpdateRequest;
import com.aizuda.boot.modules.business.contract.entity.vo.WorkflowTypeResponse;
import com.aizuda.boot.modules.common.constant.enums.ResponseCodeEnum;
import com.aizuda.boot.modules.business.contract.mapper.WorkflowTypeMapper;
import com.aizuda.boot.modules.business.contract.service.WorkflowTypeService;
import com.aizuda.boot.modules.business.contract.util.AuthUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author sangyirong
 * @ClassName WorkflowTypeServiceImpl
 * @Version 1.0
 * @Date 2025/6/10 19:13
 */
@Service
public class WorkflowTypeServiceImpl extends ServiceImpl<WorkflowTypeMapper, WorkflowTypeEntity> implements WorkflowTypeService {


    @Override
    public SingleResponse<List<WorkflowTypeResponse>> queryWorkflowTypeList() {
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser.getEmployeeId())) {
            return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), ResponseCodeEnum.NOT_LOGGED.getMsg());
        }
        // 按排序字段查询
        List<WorkflowTypeEntity> list = this.list(new LambdaQueryWrapper<WorkflowTypeEntity>()
                .orderByAsc(WorkflowTypeEntity::getTypeOrder));

        // 转换为响应对象
        List<WorkflowTypeResponse> responseList = list.stream().map(entity -> {
            WorkflowTypeResponse response = new WorkflowTypeResponse();
            BeanUtils.copyProperties(entity, response);
            return response;
        }).collect(Collectors.toList());

        return SingleResponse.of(responseList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse<Void> createWorkflowType(WorkflowTypeAddRequest request) {
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser.getEmployeeId())) {
           return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), ResponseCodeEnum.NOT_LOGGED.getMsg());
        }
        if (Objects.isNull(request) || Objects.isNull(request.getTypeName())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAM_BINDING_EXCEPTION.getCode(), ResponseCodeEnum.PARAM_BINDING_EXCEPTION.getMsg());
        }
        // 校验名称是否重复
        long count = count(new LambdaQueryWrapper<WorkflowTypeEntity>()
                .eq(WorkflowTypeEntity::getTypeName, request.getTypeName()));
        if (count > 0) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_ALREADY_EXISTS.getCode(), "流程类型名称已存在");
        }

        // 获取最大的排序值
        Integer maxOrder = this.getMaxOrder();

        // 创建实体并保存
        WorkflowTypeEntity entity = new WorkflowTypeEntity();
        BeanUtils.copyProperties(request, entity);
        entity.setTypeOrder(maxOrder + 1);
        entity.setIsSystem(false);

        this.save(entity);
        return SingleResponse.success();
    }

    @Override
    public SingleResponse<WorkflowTypeResponse> getWorkflowTypeById(Integer id) {
        if (Objects.isNull(id)) {
            return SingleResponse.failure(ResponseCodeEnum.PARAM_BINDING_EXCEPTION.getCode(), ResponseCodeEnum.PARAM_BINDING_EXCEPTION.getMsg());
        }
        // 检查是否存在
        WorkflowTypeEntity entity = this.getById(id);
        if (entity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "流程类型不存在");
        }

        WorkflowTypeResponse response = new WorkflowTypeResponse();
        BeanUtils.copyProperties(entity, response);
        return SingleResponse.of(response);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse<Void> updateWorkflowType(WorkflowTypeUpdateRequest request) {
        UserInfo currentUser = AuthUtil.getCurrentUser();
        if (Objects.isNull(currentUser.getEmployeeId())) {
            return SingleResponse.failure(ResponseCodeEnum.NOT_LOGGED.getCode(), ResponseCodeEnum.NOT_LOGGED.getMsg());
        }
        if (Objects.isNull(request) || Objects.isNull(request.getId()) || Objects.isNull(request.getTypeName())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAM_BINDING_EXCEPTION.getCode(), ResponseCodeEnum.PARAM_BINDING_EXCEPTION.getMsg());
        }
        // 检查是否存在
        WorkflowTypeEntity existingEntity = this.getById(request.getId());
        if (existingEntity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "流程类型不存在");
        }

        // 校验名称是否重复（排除自身）
        long count = this.count(new LambdaQueryWrapper<WorkflowTypeEntity>()
                .eq(WorkflowTypeEntity::getTypeName, request.getTypeName())
                .ne(WorkflowTypeEntity::getId, request.getId()));
        if (count > 0) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_ALREADY_EXISTS.getCode(), "流程类型名称已存在");
        }

        // 更新实体
        WorkflowTypeEntity entity = new WorkflowTypeEntity();
        BeanUtils.copyProperties(request, entity);

        this.updateById(entity);
        return SingleResponse.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse<Void> removeWorkflowType(Integer id) {
        if (Objects.isNull(id)) {
            return SingleResponse.failure(ResponseCodeEnum.PARAM_BINDING_EXCEPTION.getCode(), ResponseCodeEnum.PARAM_BINDING_EXCEPTION.getMsg());
        }
        // 检查是否存在
        WorkflowTypeEntity entity = this.getById(id);
        if (entity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_ALREADY_EXISTS.getCode(), "流程类型不存在");
        }

        // 获取当前排序值
        Integer currentOrder = entity.getTypeOrder();

        // 删除实体
        this.removeById(id);

        // 更新后续排序
        this.update(new LambdaUpdateWrapper<WorkflowTypeEntity>()
                .gt(WorkflowTypeEntity::getTypeOrder, currentOrder)
                .setSql("type_order = type_order - 1"));

        return SingleResponse.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SingleResponse<Void> sortWorkflowType(WorkflowTypeSortRequest request) {
        if (Objects.isNull(request) || Objects.isNull(request.getId()) || Objects.isNull(request.getTypeOrder())) {
            return SingleResponse.failure(ResponseCodeEnum.PARAM_BINDING_EXCEPTION.getCode(), ResponseCodeEnum.PARAM_BINDING_EXCEPTION.getMsg());
        }
        // 检查是否存在
        WorkflowTypeEntity entity = this.getById(request.getId());
        if (entity == null) {
            return SingleResponse.failure(ResponseCodeEnum.DATA_NOT_FOUND.getCode(), "流程类型不存在");
        }

        Integer oldOrder = entity.getTypeOrder();
        Integer newOrder = request.getTypeOrder();

        if (Objects.equals(oldOrder, newOrder)) {
            return SingleResponse.success();
        }

        // 获取最大的排序值
        Integer maxOrder = this.getMaxOrder();
        if (newOrder > maxOrder) {
            return SingleResponse.failure(ResponseCodeEnum.PARAM_BINDING_EXCEPTION.getCode(), "排序值不能大于最大排序值");
        }

        if (newOrder < 1) {
            return SingleResponse.failure(ResponseCodeEnum.PARAM_BINDING_EXCEPTION.getCode(), "排序值不能小于1");
        }

        // 更新其他记录的排序
        if (newOrder > oldOrder) {
            // 向后移动，中间的记录向前移动一位
            this.update(new LambdaUpdateWrapper<WorkflowTypeEntity>()
                    .gt(WorkflowTypeEntity::getTypeOrder, oldOrder)
                    .le(WorkflowTypeEntity::getTypeOrder, newOrder)
                    .setSql("type_order = type_order - 1"));
        } else {
            // 向前移动，中间的记录向后移动一位
            this.update(new LambdaUpdateWrapper<WorkflowTypeEntity>()
                    .ge(WorkflowTypeEntity::getTypeOrder, newOrder)
                    .lt(WorkflowTypeEntity::getTypeOrder, oldOrder)
                    .setSql("type_order = type_order + 1"));
        }

        // 更新当前记录的排序值
        entity.setTypeOrder(newOrder);
        entity.setUpdatedAt(new Date());
        this.updateById(entity);

        return SingleResponse.success();
    }

    /**
     * 获取最大排序值
     */
    private Integer getMaxOrder() {
        WorkflowTypeEntity maxEntity = this.getOne(new LambdaQueryWrapper<WorkflowTypeEntity>()
                .orderByDesc(WorkflowTypeEntity::getTypeOrder)
                .last("LIMIT 1"));
        return maxEntity != null ? maxEntity.getTypeOrder() : 0;
    }
}
